//------------------------------------------------------------------------------
// Copyright (c) 2008 www.dnaide.com
// Licensed under the MIT (MIT-LICENSE.txt)
//------------------------------------------------------------------------------
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Text;
using System.IO;
using System.Reflection;
using System.Globalization;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;

using DNAide.Core;
using DNAide.Web.UI.Scripts;

namespace DNAide.Web.UI.Controls
{

	/// <summary>
	/// Inserts a code flash movie 
	/// </summary>
	[ParseChildren(true)]
	public class FlashMovie : Control
	{
		private List<FlashInputItem> _flashInputs;
		private StringBuilder _buffer;

		#region Properties

		/// <summary>
		/// If the control relies on various javascript resources to run (e.g jQuery etc), 
		/// by default the controls will register the script resources.
		/// You can prevent this by setting this value to false
		/// </summary>
		public Boolean AutoRegisterScriptResources
		{
			get { return ((ViewState["AutoRegisterScriptResources"] == null) ? true : (bool)ViewState["AutoRegisterScriptResources"]); }
			set { ViewState["AutoRegisterScriptResources"] = value; }
		}

		/// <summary>Collection of Flash inputs</summary>	
		public List<FlashInputItem> FlashInputs
		{
			get {return _flashInputs;}
			set {_flashInputs = value;}	
		}
		
		/// <summary>The ID of the flash movie. Default = ClientID + "_FlashMovie"</summary>
		public String FlashMovieId
		{
			get { return ViewState["FlashMovieId"] == null ? ClientID + "_FlashMovie" : (string)ViewState["FlashMovieId"]; }
			set { ViewState["FlashMovieId"] = value; }	
		}

		/// <summary>The javascript variable name. Default = ClientID + "_FlashMovieVar"</summary>
		public String ScriptVariableName
		{
			get { return ViewState["ScriptVariableName"] == null ? ClientID + "_FlashMovieVar" : (string)ViewState["ScriptVariableName"]; }
			set { ViewState["ScriptVariableName"] = value; }	
		}

		/// <summary>The ID of the HTML entity to replace with the flash</summary>
		public String TargetId
		{
			get { return ViewState["TargetId"] == null ? string.Empty : (string)ViewState["TargetId"]; }
			set { ViewState["TargetId"] = value; }	
		}
		
		/// <summary>URL to the Flash Movie</summary>
		public String SwfUrl
		{
			get { return ViewState["SwfUrl"] == null ? string.Empty : (string)ViewState["SwfUrl"]; }
			set { ViewState["SwfUrl"] = value; }	
		}

		/// <summary>The width of your Flash movie.</summary>
		public String Width
		{
			get {return ViewState["Width"] == null ? "100" : (string) ViewState["Width"];}
			set {ViewState["Width"] = value;}	
		}

		/// <summary>The height of your Flash movie.</summary>
		public String Height
		{
			get {return ViewState["Height"] == null ? "100" : (string) ViewState["Height"];}
			set {ViewState["Height"] = value;}	
		}

		/// <summary>The required player version for your Flash content. This can be a string in the format of 'majorVersion.minorVersion.revision'. An example would be: "6.0.65". Or you can just require the major version, such as "6". Default = 7</summary>
		public String FlashPlayerVersion
		{
			get {return ViewState["FlashPlayerVersion"] == null ? "7" : (string) ViewState["FlashPlayerVersion"];}
			set {ViewState["FlashPlayerVersion"] = value;}	
		}

		/// <summary>This is the hex value of the background color of your Flash movie. Default = #ffffff</summary>
		public String BackColor
		{
			get {return ViewState["BackColor"] == null ? "#ffffff" : (string) ViewState["BackColor"];}
			set {ViewState["BackColor"] = value;}	
		}

		/// <summary>If you would like to upgrade users using the ExpressInstall feature. Default true</summary>
		public Boolean UseExpressInstall
		{
			get {return ViewState["UseExpressInstall"] == null ? true : (bool) ViewState["UseExpressInstall"];}
			set {ViewState["UseExpressInstall"] = value;}	
		}


		/// <summary>Url to the expressinstall.swf</summary>
		public String ExpressInstallSwfUrl
		{
			get { return ViewState["ExpressInstallSwfUrl"] == null ? string.Empty : (string)ViewState["ExpressInstallSwfUrl"]; }
			set { ViewState["ExpressInstallSwfUrl"] = value; }
		}

		/// <summary>If you would like to redirect users who complete the ExpressInstall upgrade, you can specify an alternate URL here</summary>
		public String ExpressInstallRedirectUrl
		{
			get { return ViewState["ExpressInstallRedirectUrl"] == null ? string.Empty : (string)ViewState["ExpressInstallRedirectUrl"]; }
			set { ViewState["ExpressInstallRedirectUrl"] = value; }	
		}

		/// <summary>The quality you wish your Flash movie to play at. If no quality is specified, the default is "high"</summary>
		public String Quality
		{
			get {return ViewState["Quality"] == null ? "high" : (string) ViewState["Quality"];}
			set {ViewState["Quality"] = value;}	
		}

		/// <summary>If you wish to redirect users who don't have the correct plug-in version, use this parameter and they will be redirected.</summary>
		public String RedirectUrl 
		{
			get {return ViewState["RedirectUrl"] == null ? string.Empty : (string) ViewState["RedirectUrl"];}
			set {ViewState["RedirectUrl"] = value;}	
		}

		/// <summary>This is the url variable name the SWFObject script will look for when bypassing the detection. Default is 'detectflash'. Example: To bypass the Flash detection and simply write the Flash movie to the page, you could add ?detectflash=false to the url of the document containing the Flash movie.</summary>
		public String DetectKey 
		{
			get {return ViewState["DetectKey"] == null ? "'detectflash'" : (string) ViewState["DetectKey"];}
			set {ViewState["DetectKey"] = value;}	
		}

		/// <summary>
		/// Whether the JS is fired on document ready or inline
		/// </summary>
		public Boolean LoadOnDocumentReady
		{
			get { return ViewState["LoadOnDocumentReady"] == null ? false : (bool)ViewState["LoadOnDocumentReady"]; }
			set { ViewState["LoadOnDocumentReady"] = value; }	
		}

		#endregion

		/// <summary></summary>
		public FlashMovie()
		{
			_flashInputs = new List<FlashInputItem>();
		}

		/// <summary></summary>
		/// <param name="e"></param>
		protected override void OnPreRender(EventArgs e)
		{
			if (String.IsNullOrEmpty(SwfUrl))
			{
				throw new ArgumentException(Resources.FlashMovie.UrlRequired);
			}

			if (String.IsNullOrEmpty(TargetId))
			{
				throw new ArgumentException(Resources.FlashMovie.TagetIdRequired);
			}

			if (this.AutoRegisterScriptResources)
			{
				if (this.LoadOnDocumentReady)
				{
					ScriptAide.RegisterDNAideResource(DNAideScriptResource.JQuery);
				}
				ScriptAide.RegisterDNAideResource(DNAideScriptResource.SwfObject);
			}

			this._buffer = new StringBuilder();

			if (this.LoadOnDocumentReady)
			{
				_buffer.AppendFormat("jQuery('document').ready(function(){{\r\nvar {0} = new SWFObject(\"{1}\", \"{2}\", \"{3}\", \"{4}\", \"{5}\", \"{6}\", \"{7}\", \"{8}\", \"{9}\", \"{10}\");\r\n", ScriptVariableName, UrlAide.Resolve(SwfUrl), FlashMovieId, Width, Height, FlashPlayerVersion, BackColor, Quality, UrlAide.Resolve(ExpressInstallRedirectUrl), UrlAide.Resolve(RedirectUrl), DetectKey);

			}
			else
			{
				_buffer.AppendFormat("<script type=\"text/javascript\">\r\n//<![CDATA[\r\nvar {0} = new SWFObject(\"{1}\", \"{2}\", \"{3}\", \"{4}\", \"{5}\", \"{6}\", \"{7}\", \"{8}\", \"{9}\", \"{10}\");\r\n", ScriptVariableName, UrlAide.Resolve(SwfUrl), FlashMovieId, Width, Height, FlashPlayerVersion, BackColor, Quality, UrlAide.Resolve(ExpressInstallRedirectUrl), UrlAide.Resolve(RedirectUrl), DetectKey);

			}
			
			if (UseExpressInstall)
			{
				if (string.IsNullOrEmpty(ExpressInstallSwfUrl))
				{
					_buffer.AppendFormat("{0}.useExpressInstall();\r\n", ScriptVariableName);
				}
				else
				{
					_buffer.AppendFormat("{0}.useExpressInstall('{1}');\r\n", ScriptVariableName, UrlAide.Resolve(ExpressInstallSwfUrl));
				}

			}

			foreach (FlashInputItem anInputItem in FlashInputs)
			{
				if (anInputItem.InputType == FlashInputType.Parameter || anInputItem.InputType == FlashInputType.Both)
					_buffer.AppendFormat("{0}.addParam(\"{1}\", \"{2}\");\r\n", ScriptVariableName, anInputItem.Name, anInputItem.Value);

				if (anInputItem.InputType == FlashInputType.Variable || anInputItem.InputType == FlashInputType.Both)
					_buffer.AppendFormat("{0}.addVariable(\"{1}\", \"{2}\");\r\n", ScriptVariableName, anInputItem.Name, anInputItem.Value);
			}

			if (this.LoadOnDocumentReady)
			{
				_buffer.AppendFormat("{0}.write(\"{1}\");\r\n}});", ScriptVariableName, TargetId);
				ScriptAide.RegisterEmbed(_buffer.ToString());
			}
			else
			{
				_buffer.AppendFormat("{0}.write(\"{1}\");\r\n//]]>\r\n</script>", ScriptVariableName, TargetId);
			}
			
			base.OnPreRender(e);
		}

		/// <summary></summary>
		/// <param name="writer"></param>
		protected override void Render(HtmlTextWriter writer)
		{
			if (!this.LoadOnDocumentReady)
			{
				writer.Write(_buffer.ToString());
			}
		}

	}


	/// <summary></summary>
	public class FlashInputItem
	{
		private string _name;
		private string _value;
		private FlashInputType _inputType;
		
		/// <summary></summary>
		public string Name
		{
			get {return _name;}
			set {_name = value;}
		}

		/// <summary></summary>
		public string Value
		{
			get {return _value;}
			set {_value = value;}
		}

		/// <summary></summary>
		public FlashInputType InputType
		{
			get {return _inputType;}
			set {_inputType = value;}
		}

		/// <summary></summary>
		public FlashInputItem()
		{
			_name = string.Empty;
			_value = string.Empty;
			_inputType = FlashInputType.Both;
		}

		/// <summary></summary>
		/// <param name="name"></param>
		/// <param name="value"></param>
		/// <param name="inputType"></param>
		public FlashInputItem(string name, string value, FlashInputType inputType)
		{
			_name = name;
			_value = value;
			_inputType = inputType;
		}
	}
}
